<?php
/**
 * Created by User: wene<china_wangyu@aliyun.com> Date: 2019/4/12 Time: 16:47
 */
namespace think\restful\helper;

use think\restful\exception\ApiException;
use think\restful\reflex\Reflex;

/**
 * Trait Helper 扩展帮助工具类
 * @package think\restful\helper
 */
trait Helper
{
    /**
     * 清洗数据
     * @param string $str
     * @return string
     */
    public static function cleanText(string $str = ''){
        return strtolower(substr(str_replace(' ','_',trim($str)),0,40));
    }

    /**
     * 创建目录，并设置权限
     * @param string $path
     * @return bool
     */
    public static function dir(string $path = ''){
        if(empty($path)) return false;
        is_file($path) &&  $path = dirname($path);
        $res = mkdir($path, 0755, true);
        $res1 = chmod($path, 0777);
        return $res == $res1 && $res == 1 ? true: false;
    }

    /**
     * 写入数据
     * @param string $path 文件路径
     * @param string $data  文件数据
     * @param int $flags file_put_content flags参数
     * @return bool|int 返回数据 或 false
     */
    public static function write(string $path,string $data = '',$flags = FILE_APPEND|LOCK_EX){
        return file_put_contents($path,$data,$flags);
    }

    /**
     * 获取文件夹内容
     * @param string $dir 文件夹路径
     * @param array $ignore 过滤名称列表 ['name','name1']
     * @param string $ext 后缀名
     * @return array
     */
    public static function folder(string $dir,array $ignore = [],string $ext = '.php')
    {
        $fileList = glob($dir .DIRECTORY_SEPARATOR. '*' . $ext);
        if(empty($ignore)) return $fileList;
        $ignoreList = null;
        foreach ($ignore as $value){
            $ignoreList[] = $dir .DIRECTORY_SEPARATOR.$value. $ext;
        }
        return array_diff($fileList,$ignoreList);
    }

    /**
     * 获取API版本反射数据
     * @param array $config
     * @return array|null
     */
    public static function getApiVersionReflexData(array $config = []):?array {
        try{
            $data = [];
            $path = env('APP_PATH') . $config['API_MODULE'] . DIRECTORY_SEPARATOR.
                $config['API_CONTROLLER']. DIRECTORY_SEPARATOR;
            $apiNamespace = DIRECTORY_SEPARATOR.env('APP_NAMESPACE').DIRECTORY_SEPARATOR
                .$config['API_MODULE'].DIRECTORY_SEPARATOR.$config['API_CONTROLLER'].
                DIRECTORY_SEPARATOR;
            foreach ($config['API_VERSION'] as $version){
                foreach (static::getVersionData($version,$apiNamespace,$path,$config) as $datum){
                    $data[$version] = $datum;
                }
            }
            return $data;
        }catch (\Exception $exception){
            ApiException::exception('500 '.$exception->getMessage());
        }
    }

    /**
     * 获取API版本反射数据
     * @param $version
     * @param $apiNamespace
     * @param $path
     * @param $config
     * @return array|\Generator
     */
    private static function getVersionData($version,$apiNamespace,$path,$config){
        $apiObjectReflex = [];
        $apiNamespace .= $version.DIRECTORY_SEPARATOR;
        $apiList = Helper::folder($path . $version, $config['API_IGNORE_CONTROLLER'], $config['API_EXT']);
        if (empty($apiList)) return [];
        foreach ($apiList as $apiListIndex => $api){
            $newApiClass = $apiNamespace. basename($api,$config['API_EXT']);
            $object = new $newApiClass(true);
            $reflex = new Reflex($object);
            $apiObjectReflex[$newApiClass] = $reflex->object();
        }
        yield $apiObjectReflex;
    }

    // 创建markdown文档TOC
    public static function toMarkdownToc(array $data,string $path):void {
        if(empty($data) or empty($path)) ApiException::exception('参数不能为空~');
        foreach (static::getMarkdownTocContent($data) as $tocContent){
            Helper::write($path,$tocContent);
        }
    }

    // 获取markdown文档TOC内容
    private static function getMarkdownTocContent($data){
        $fileContent = '# API文档目录'.PHP_EOL;
        foreach ($data as $version => $versionData){
            $versionDocReflex = Helper::cleanText($version);
            $fileContent .= '- ['.$versionDocReflex.'](#'.$versionDocReflex.')'.PHP_EOL;
            foreach ($versionData as $classReflex){
                $objectDocReflex = Helper::cleanText($classReflex['object'][0]);
                $fileContent .= '   - ['.$objectDocReflex.'](#'.$objectDocReflex.')'.PHP_EOL;
                foreach ($classReflex['methods'] as $index => $method){
                    $actionDocReflex = Helper::cleanText($index.$method['doc']['value']);
                    $fileContent .= '       - ['.$actionDocReflex.'](#'.$actionDocReflex.')'.PHP_EOL;
                }
            }
            yield $fileContent;
        }
    }

    // 输出API接口类
    public static function toMarkdownClass(array $objectData = []):?string {
        $fileContent = '';
        if(!empty($objectData)){
            foreach ($objectData as $index => $item){
                if ($index == 0){
                    $fileContent .= '## '.Helper::cleanText($item).PHP_EOL.PHP_EOL;
                }else{
                    $fileContent .= '-  '.trim($item).PHP_EOL;
                }
            }
        }
        return $fileContent;
    }

}